#include "CoordCom.h"

extern FrameAPI gl_CurrentFrameAPI;

void sendInfoToAllSensors(unsigned char* info, int dataLen)
{
    unsigned char adresseDEST_H[4] = {0x00, 0x00, 0x00, 0x00};
    unsigned char adresseDEST_L[4] = {0x00, 0x00, 0xFF, 0xFF};
    unsigned char adresseDEST_16bits_Broadcast[2] = {0xFF, 0xFE};

    makeDataTransmitFrame(info, dataLen, adresseDEST_H, adresseDEST_L,adresseDEST_16bits_Broadcast);

    sendAPI();

    waitForTransmitStatusPacket();
}

void sendInfoToOneSensor(unsigned char* info, unsigned char nodeID, int dataLen)
{
    unsigned char adresseDEST_H[4] = {0x00, 0x00, 0x00, 0x00};
    unsigned char adresseDEST_L[4] = {0x00, 0x00, 0x00, 0x00};
    unsigned char adresseDEST_16bits[2] = {0xFF,0xFE};

    if (getDestinationAddressFromRouteTable(nodeID, adresseDEST_H, adresseDEST_L) != DESTINATION_UNKNOWN)
    {
        makeDataTransmitFrame(info, dataLen, adresseDEST_H, adresseDEST_L, adresseDEST_16bits);
    }

    sendAPI();

    waitForTransmitStatusPacket();
}

void initCoord(void)
{
    init_MicroController();
    gl_RouteTable.curTableIndex = 0;
    initClock();
    initialisationUSART1();
}

void handleDataPacket(void)
{
    int iIndex = 0;
    int isRegister;
    switch(gl_CurrentFrameAPI.content.frame.api.receivePacket.rcvData[0])
    {
        case SENSOR_DATA_PACKET :
            allumerLed(LED_ERROR);
            parseSensorData();
            iIndex = tryGetEntryIndexFromAddress(gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64H, gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64L);
            if(iIndex >= 0)
            {
                delaySec(2);
                eteindreLed(LED_ERROR);
                gl_RouteTable.Entries[iIndex].entry_ErrorCount = 0;
            }
            break;

        case SENSOR_REGISTER_REQUEST :

            isRegister = TRUE;
            iIndex = tryGetEntryIndexFromAddress(gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64H, gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64L);
            // if the address isn't already in the route table
            if(iIndex == -1)
            {
                // Create a new entry
                isRegister = addRouteTableEntry(gl_RouteTable.curTableIndex, gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64H, gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64L);
                // if the table is not full then the Sensor is registered
            }
            sendRegisterResponse(gl_RouteTable.Entries[iIndex].entry_NI, isRegister);
            break;
            
        case SENSOR_UNREGISTER_REQUEST :
            iIndex = tryGetEntryIndexFromAddress(gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64H, gl_CurrentFrameAPI.content.frame.api.receivePacket.srcAdd64L);
            if(iIndex != -1)
            {
                allumerLed(LED_ERROR);
                delaySec(2);
                eteindreLed(LED_ERROR);
                removeRouteTableEntry(iIndex);
            }
            break;
    }
}

void sendRegisterResponse(unsigned char nodeID_dest, char ok)
{
    unsigned char data[4];
    char dataLen = 2;
    data[0] = COORD_REGISTER_RESPONSE;
    if (ok == TRUE)
    {
        data[1] = REGISTER_SUCCESS;
        data[2] = getTimeLeft(WD_COORD_SENSOR_APPLI);
        data[3] = SLEEP_TIME_PERIOD;
        dataLen += 2;
    }
    else
    {
        data[1] = REGISTER_FAILURE;
    }
    sendInfoToOneSensor(data, nodeID_dest, dataLen);
}

void parseSensorData(void)
{/*
    unsigned char iIndex = 0;
    unsigned char iIndexRt_MatchingDevice = 0;
    int iFrameSize = gl_CurrentFrameAPI.length_MSB * 256 + gl_CurrentFrameAPI.length_LSB;
    FILE* fOut = fopen("out.tmp","a+");

    unsigned char buffer[5];

    while(gl_CurrentFrameAPI.content.frame.api.receivePacket.rcvData[iIndex + 1] != '*')
    {
        buffer[iIndex] = gl_CurrentFrameAPI.content.frame.api.receivePacket.rcvData[iIndex + 1];
        iIndex ++;
    }
    buffer[iIndex] = '\0';

    iIndexRt_MatchingDevice = tryGetEntryIndex(buffer);

    if(iIndexRt_MatchingDevice == -1)
    {
        printf("<!>ERROR - Data Packet Received From unregistered Device - Ignored\n");
        fclose(fOut);
        return;
    }

    fprintf(fOut,"%d - ", getCurDate());
    printf("%d - ", getCurDate());

    gl_RouteTable.Entries[iIndexRt_MatchingDevice].entry_ErrorCount = 0;
    fprintf(fOut,"%s", buffer);
    printf("%s", buffer);

    buffer[0] = gl_CurrentFrameAPI.content.frame.api.receivePacket.rcvData[iIndex + 1];
    while(iIndex < iFrameSize)
    {
        if(gl_CurrentFrameAPI.content.data[iIndex] == '*')
        {
            fprintf(fOut,";");
            printf(";");
        }
        else
        {
            fprintf(fOut,"%x", (unsigned char)gl_CurrentFrameAPI.content.data[iIndex]);
            printf("%x", (unsigned char)gl_CurrentFrameAPI.content.data[iIndex]);
        }
        iIndex ++;
    }
    printf("\n");
    fclose(fOut);*/
}

void sendRequestData(unsigned char nodeID_dest)
{
    unsigned char data[1];
    data[0] = COORD_DATA_REQUEST;
    sendInfoToOneSensor(data, nodeID_dest, 1);
}

int requestDataFromFirstNonResponding(void)
{
    int iCpt;
    for(iCpt = 0 ; iCpt < gl_RouteTable.curTableIndex ; iCpt ++ )
    {
        if((gl_RouteTable.Entries[iCpt].entry_ErrorCount > 0 )&&(gl_RouteTable.Entries[iCpt].entry_ErrorCount < 5))
        {
            sendRequestData(gl_RouteTable.Entries[iCpt].entry_NI);
            return iCpt;
        }
    }
    return -1;
}
